package com.kingmed.kmss.bpmn.flow.command;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.ManagementService;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.kingmed.kmss.common.bo.bpmn.ProcessDefinitionBO;
import com.kingmed.kmss.common.bo.bpmn.ProcessInstanceBO;
import com.kingmed.kmss.common.bo.bpmn.UserBO;
import com.kingmed.kmss.common.qc.bpmn.ProcessQueryCondition;
import com.kingmed.kmss.common.utils.BeanCopyUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * 直接通过自定义sql查询flowable数据库，调用mapper的sql
 */
@Slf4j
@Service
public class ProcessSqlCommand {

	@Autowired
	ManagementService managementService;

	public ProcessSqlCommand(ManagementService managementService) {
		super();
		this.managementService = managementService;
//		managementService = AppContextUtil.getBean(ManagementService.class);
		//执行数据库操作
	}

	public ProcessDefinitionBO findLatestVersionProcessDefinitionByKey(String processKey) {

		Map<String, Object> paramMap = new HashMap<>();
		paramMap.put("processKey", processKey);

		ProcessDefinitionBO resultSet = managementService.executeCommand(new Command<ProcessDefinitionBO>() {
			@Override
			public ProcessDefinitionBO execute(CommandContext commandContext) {
				return (ProcessDefinitionBO) CommandContextUtil.getDbSqlSession()
						.selectOne("selectLatestVersionProcessDefinitionByKey", paramMap);
			}
		});
		log.info(" findMyLastestProcessDefinitionByKey() result is: {}", resultSet);
		return resultSet;
	}

	public ProcessDefinitionBO findProcessDefinitionById(String processId) {

		ProcessDefinitionBO resultSet = managementService.executeCommand(new Command<ProcessDefinitionBO>() {
			@Override
			public ProcessDefinitionBO execute(CommandContext commandContext) {
				return (ProcessDefinitionBO) CommandContextUtil.getDbSqlSession()
						.selectOne("selectMyProcessDefinitionById", processId);
			}
		});
		log.info(" findProcessDefinitionById() result is: {}", resultSet);
		return resultSet;
	}

	public ProcessInstanceBO findProcessByExecutionId(String executionId) {

		ProcessInstanceBO resultSet = managementService.executeCommand(new Command<ProcessInstanceBO>() {
			@Override
			public ProcessInstanceBO execute(CommandContext commandContext) {
				return (ProcessInstanceBO) CommandContextUtil.getDbSqlSession()
						.selectOne("selectProcessComboByExecutionId", executionId);
			}
		});
		if (resultSet != null) {
			if (resultSet.getParentInstanceId() == null)
				resultSet.setIsRootProcess("1");
			else
				resultSet.setIsRootProcess("0");
		}
		log.info(" findProcessByExecutionId() result is: {}", resultSet);

		return resultSet;
	}

	public List<ProcessInstanceBO> findProcessByInstanceId(String processInstanceId) {

		List<ProcessInstanceBO> resultSet = managementService.executeCommand(new Command<List<ProcessInstanceBO>>() {
			@SuppressWarnings("unchecked")
			@Override
			public List<ProcessInstanceBO> execute(CommandContext commandContext) {
				return (List<ProcessInstanceBO>) CommandContextUtil.getDbSqlSession()
						.selectListWithRawParameter("selectProcessComboByInstanceId", processInstanceId);
			}
		});

		if (resultSet != null)
			log.info("Sql select result count is: {}", resultSet.size());
		else
			log.info(" No matched result.");
		log.info(" findProcessByInstanceId() result is: {}", resultSet);

		return resultSet;
	}

	public List<ProcessInstanceBO> findProcessByBizKey(String bizKey) {

		ProcessQueryCondition qryCond = new ProcessQueryCondition();
		qryCond.setBusinessKey(bizKey);

		Map<String, Object> paramMap  = BeanCopyUtils.copyToMap(qryCond);

		List<ProcessInstanceBO> resultSet = managementService.executeCommand(new Command<List<ProcessInstanceBO>>() {
			@SuppressWarnings("unchecked")
			@Override
			public List<ProcessInstanceBO> execute(CommandContext commandContext) {
				return (List<ProcessInstanceBO>) CommandContextUtil.getDbSqlSession()
						.selectListWithRawParameter("selectProcessComboByCondition", paramMap);
			}
		});

		if (resultSet != null)
			log.info("Sql select result count is: {}", resultSet.size());
		else
			log.info(" No matched result.");
		log.info(" findProcessByBizKey() result is: {}", resultSet);

		return resultSet;
	}

	public List<ProcessInstanceBO> findProcessByCondition(ProcessQueryCondition qryCond) {

		Map<String, Object> paramMap = new HashMap<>();

		BeanCopyUtils.copyToMap(qryCond);

		List<ProcessInstanceBO> resultSet = managementService.executeCommand(new Command<List<ProcessInstanceBO>>() {
			@SuppressWarnings("unchecked")
			@Override
			public List<ProcessInstanceBO> execute(CommandContext commandContext) {
				return (List<ProcessInstanceBO>) CommandContextUtil.getDbSqlSession()
						.selectListWithRawParameter("selectProcessComboByCondition", paramMap);
			}
		});

		if (resultSet != null)
			log.info("Sql select result count is: {}", resultSet.size());
		else
			log.info(" No matched result.");

		log.info(" findProcessByCondition() result is: {}", resultSet);

		return resultSet;
	}

	public UserBO findUserById(String userId) {

		Map<String, Object> paramMap = new HashMap<>();
		paramMap.put("userId", userId);

		UserBO resultSet = managementService.executeCommand(new Command<UserBO>() {
			@Override
			public UserBO execute(CommandContext commandContext) {
				return (UserBO) CommandContextUtil.getDbSqlSession().selectOne("findUserById", paramMap);
			}
		});
		log.info(" findUserById() result is: {}", resultSet);
		return resultSet;
	}
}
